# -*- coding: utf-8 -*-
# 该文件在宿主机执行，需要 root 权限
# 要求 docker 内部的主机名称与 docker 容器的名称都为 router.name

import os
from build_router import config_net
from config import config, router



if __name__ == "__main__":
    config = config()
    
    """1. 创建 docker 容器"""
    # Docker Compose 已弃用
    # os.system(f"sudo docker-compose up --scale router={len(config.routers)} -d")
    # os.system(f"sudo docker-compose up --scale device={len(config.devices)} -d")

    # 更新 dockerfile 后执行：
    os.system("sudo docker build -t quagga_ubuntu .")

    for router in config.routers:
        os.system(f"sudo docker create -it --name={router.name} --net=none --privileged quagga_ubuntu:latest /bin/bash")
        os.system(f"sudo docker start {router.name}")
    for device in config.devices:
        os.system(f"sudo docker create -it --name={device.name} --net=none --privileged quagga_ubuntu:latest /bin/bash")
        os.system(f"sudo docker start {device.name}")

    """2. 配置宿主机网络"""
    nets = []   # 保存已经创建的网络名称

    for router in config.routers:
        for i in range(len(router.interfaces_ip)):
            net_name = router.get_network_name(i)
            # nets 中没找到，说明该网络没创建，则在宿主机中创建该网络
            if router.interfaces_ip[i][-1:] == '1':
                l1 = net_name + '1'
                l2 = net_name + '2'
            else:
                l1 = net_name + '2'
                l2 = net_name + '1'
            if net_name not in nets:
                nets.append(net_name)
                os.system(f"sudo ip link add {l1} type veth peer name {l2}")     # veth - Virtual ethernet interface
            # 更改设备名为 l1 的虚拟网桥，让设备处理 PID 对应的 docker 容器
            os.system(f"sudo ip link set dev {l1} netns $(sudo docker inspect -f '{{{{.State.Pid}}}}' {router.name})")
    
    for device in config.devices:
        for i in range(len(device.interfaces_ip)):
            net_name = device.get_network_name(i)   # 先创建完了路由器，肯定存在 link
            l1 = net_name + '2'
            os.system(f"sudo ip link set dev {l1} netns $(sudo docker inspect -f '{{{{.State.Pid}}}}' {device.name})")

    """3. 在 docker 容器内部运行配置文件"""
    for router in config.routers:
        os.system(f"sudo docker exec -itd {router.name} /bin/python3.8 ./build_router.py {router.name}")
    for device in config.devices:
        os.system(f"sudo docker exec -itd {device.name} /bin/python3.8 ./build_router.py {device.name}")
